public import tango.stdc.stringz;
public import tango.stdc.string;
public import derelict.sdl.sdl;
public import derelict.opengl.gl;
public import derelict.opengl.glu;
import tango.core.Thread;
import tango.time.Clock;

import tango.io.Stdout;
import tango.math.Math;

float[][] pts,shadow;
float[2] pos;


void initGL(int xResolution, int yResolution)
{
	
			// initialize SDL, GL and GLU Derelict modules
	DerelictSDL.load();
	DerelictGL.load();

	DerelictGLU.load();

	const int bitsPerPixel=24;
	
	// initialize SDL's VIDEO module
	SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);

	// enable double-buffering
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
	
	const char[] name="TEST";
	
	// create our OpenGL window
	SDL_SetVideoMode(xResolution, yResolution, bitsPerPixel, SDL_OPENGL);
	SDL_WM_SetCaption(toStringz(name), null);

	setupGL(xResolution, yResolution);
}
// be nice and release all resources
void cleanup() {
	// tell SDL to quit
	SDL_Quit();

	// release GL, GLU and SDL's shared libs
	DerelictGLU.unload();
	DerelictGL.unload();
	DerelictSDL.unload();
}
void setupGL(int xResolution, int yResolution)
{
	
	
	glViewport(0,0,xResolution,yResolution);



	// switch to the projection mode matrix
	glMatrixMode(GL_PROJECTION);

	// load the identity matrix for projection
	glLoadIdentity();

	// setup a perspective projection matrix
	
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	
	// L/R/B/T
	gluOrtho2D(-3,3,-3,3);
	
	
	// switch back to the modelview transformation matrix
	glMatrixMode(GL_MODELVIEW);

	// load the identity matrix for modelview
	glLoadIdentity();
}
void draw()
{
	glPushAttrib(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_ENABLE_BIT);
	
	glClearStencil(0);
	glClear(GL_STENCIL_BUFFER_BIT);
	glColorMask(0,0,0,0);
	glDepthMask(0);

	//## enable stencil buffer
	glEnable(GL_STENCIL_TEST);
	//## write a one to the stencil buffer everywhere we are about to draw
	glStencilFunc(GL_ALWAYS, 0x1, 0x1);
	//## this is to always pass a one to the stencil buffer where we draw
	glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
	
	glColor3f(1,1,1);
	glBegin(GL_QUADS);
        glVertex3f (-1.0, 0.0, 0.0);
        glVertex3f (0.0, 1.0, 0.0);
        glVertex3f (1.0, 0.0, 0.0);
        glVertex3f (0.0, -1.0, 0.0);
    glEnd();

	glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
	//glDepthMask(GL_TRUE);
	
	glStencilFunc(GL_EQUAL, 0, 0x1);

	//## don't modify the contents of the stencil buffer
	glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
	glPushMatrix();
	glScalef(3,3,1);
	glBegin(GL_QUADS);
		glColor3f(1,0,0);
        glVertex3f (-1.0, 0.0, 0.0);
        glColor3f(0,1,0);
        glVertex3f (0.0, 1.0, 0.0);
        glColor3f(0,0,1);
		glVertex3f (1.0, 0.0, 0.0);
		glColor3f(1,0,1);
        glVertex3f (0.0, -1.0, 0.0);
    glEnd();

	glPopMatrix();

	glDisable(GL_STENCIL_TEST);
	glPopAttrib();
        


}

void loop()
{
		SDL_Event event;
		scope(exit) cleanup();      // when we exit, perform cleanup

		auto T=Clock();
		long delta;
		float max_fps=20;
		float interval=1/max_fps;
		long startTime,initialTime=T.now().ticks();
		float elapsed,elapsed_acc;
		int counter;
		
		mainLoop:
		while (true)
		{
			startTime=T.now().ticks();
			elapsed=0.1f;
			// handle all SDL events that we might've received in this loop iteration
			while (SDL_PollEvent(&event)) {
				switch (event.type) {
					// user has clicked on the window's close button
					case SDL_QUIT:
						break mainLoop;
						
					case SDL_KEYDOWN:
						auto evt=cast(SDL_KeyboardEvent)event;
						
						if (evt.keysym.sym==27) break mainLoop;
						
						break;
					
					
					// by default, we do nothing => break from the switch
					default:
						break;
				}
			}
			
			
			// clear the screen. by default it clears to black
			glClear(GL_COLOR_BUFFER_BIT);
			draw();
			// swap the buffers, making our backbuffer the visible one
			SDL_GL_SwapBuffers();
			
			
			elapsed=(T.now().ticks()-startTime)*0.0000001;
			elapsed_acc+=elapsed;
			counter++;
			if (counter>1000)
			{
				Stdout.formatln("average t/frame (ms): {}",elapsed_acc/counter*10000f);
				elapsed_acc=0f;
				counter=0;
				
			}
			if (elapsed>0)
				Thread.sleep(interval-elapsed);
			
		}
	
}

int main()
{
	initGL(640,400);
	loop();
	return 0;
}
